package com.lnsoft.cac.server.handle.webservice.MsgHandle;

import com.lnsoft.cac.server.Entity.Command;
import com.lnsoft.cac.server.handle.CACGlobalData;
import com.lnsoft.cac.server.handle.codec.Device;
import com.lnsoft.cac.server.handle.codec.frameMessage.*;
import com.lnsoft.cac.server.handle.codec.frameMessage.Cfg_Time_Msg;
import com.lnsoft.cac.server.handle.codec.frameMessage.FrameFactory;
import io.netty.buffer.ByteBuf;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.xml.sax.InputSource;

import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Iterator;

import lombok.extern.slf4j.Slf4j;


@Slf4j
@Component
public class DownloadCAGCtrl {
    @Autowired
    private CACGlobalData cacGlobalData;

    public void parseCAGCtrlMsg(String strXMLParams) throws Exception {
        SAXBuilder builder = new SAXBuilder();
        StringReader read = new StringReader(strXMLParams);
        InputSource source = new InputSource(read);
        Document document = builder.build(source);
        Element request = document.getRootElement();//获取根节点

        Element commands = request.getChild("commands");
        if (commands == null) {
            log.info("error:strXMLParams!");
        }
        List commandList = commands.getChildren("command");
        if (commandList == null) {
            log.info("error:commandList!");
        }
        Iterator iter = commandList.iterator();
        while (iter.hasNext()) {
            Element command = (Element) iter.next();
            String strCommandId = command.getAttributeValue("commandid"); // 命令ID
            String strDeviceId = command.getAttributeValue("objid");      // 设备ID
            String commandType = command.getAttributeValue("type");       // 命令类型
            String measurePointNo = command.getAttributeValue("measurepointno"); // 监测点
            log.info("download command：{}", commandType);

            //  如果指令和CAC相关
            if (strDeviceId.equals(cacGlobalData.cacDeviceID)) {
                log.info("CAG请求CAC自身数据:{}", strDeviceId);

                if (commandType.equals("CACID")) {
                    UploadCACConfig uploadCACConfig = new UploadCACConfig();
                    uploadCACConfig.setConfigNodeAttr(strDeviceId, measurePointNo, strCommandId);
                    uploadCACConfig.addAttrNode("CACID", cacGlobalData.cacDeviceID);
                } else if (commandType.equals("DEVICEIDNUM")) {  // 监测装置数目
                    UploadCACConfig uploadCACConfig = new UploadCACConfig();
                    uploadCACConfig.setConfigNodeAttr(strDeviceId, measurePointNo, strCommandId);
                    uploadCACConfig.addAttrNode("DEVICEIDNUM", Integer.toString(cacGlobalData.deviceMap4Device.size()));
                } else if (commandType.equals("Heartbeatcycle")) {  // 心跳周期
                    UploadCACConfig uploadCACConfig = new UploadCACConfig();
                    uploadCACConfig.setConfigNodeAttr(strDeviceId, measurePointNo, strCommandId);
                    uploadCACConfig.addAttrNode("Heartbeatcycle", "5");
                } else if (commandType.equals("CACClocktime")) {   // CAC时钟
                    UploadCACConfig uploadCACConfig = new UploadCACConfig();
                    uploadCACConfig.setConfigNodeAttr(strDeviceId, measurePointNo, strCommandId);
                    uploadCACConfig.addAttrNode("CACClocktime", Util.getDateTime());
                } else if (commandType.equals("SoftwareVersion")) {   // 软件版本
                    UploadCACConfig uploadCACConfig = new UploadCACConfig();
                    uploadCACConfig.setConfigNodeAttr(strDeviceId, measurePointNo, strCommandId);
                    uploadCACConfig.addAttrNode("SoftwareVersion", "V1.0.0.1.20190726");
                } else if (commandType.equals("CACManufacturer")) {  // 生产厂家
                    UploadCACConfig uploadCACConfig = new UploadCACConfig();
                    uploadCACConfig.setConfigNodeAttr(strDeviceId, measurePointNo, strCommandId);
                    uploadCACConfig.addAttrNode("CACManufacturer", "鲁能软件");
                } else {
                    log.info("CAC commandType is error.commandType：{}", commandType);
                }
                //  TODO    发送CAC配置信息给CAG，通过webservice。
                continue;
            }


            // 如果指令和电压检测设备相关
            Device device = cacGlobalData.deviceMap4Device.get(strDeviceId);
            if (device == null) {  // 没找到电压监测装置
                log.warn("local CAC not find Device：{}", strDeviceId);
                //  TODO
                continue;
            }
            if (device.getChannelId() == null) {  // 电压监测装置不在线
                log.warn("Device status is BREAK");
                //  TODO
                continue;
            }
            //  初始化指令信息
            Command cmd = new Command();
            cmd.setCmd_id(strCommandId);
            cmd.setCmd_type(commandType);
            cmd.setMeasurepointno(measurePointNo);

            //  将指令分发到对应的装置上
            device.getCagCmdList().offer(cmd);

            //获取命令序列号
            int frameNo = device.getFraSerNum4CAC();

            //  查询配置相关指令
            if (commandType.equals("GETCONFIG")) { //查询配置信息
                Element action = command.getChild("action");
                String strName = action.getAttributeValue("name");
                log.info(strName);

                // 加入action name
                cmd.setAction(strName);

                // 电压监测仪时间查询
                if (strName.equals("ClocktimeStamp")) {
                    Cfg_Time_Msg cfgTimeMsg = new Cfg_Time_Msg();
                    cfgTimeMsg.setRequest_Set_Flag(0x00);//查询
                    cfgTimeMsg.setClocktime_Stamp(FrameFactory.currentTimeSeconds());
                    cmd.setCmdFrame(FrameFactory.cfg_time_SendFrame(strDeviceId.getBytes(), frameNo, cfgTimeMsg.toByteBuf()));
                    return;
                }
                // 通信参数查询
                if (strName.equals("APN") || strName.equals("Heartbeatcycle") || strName.equals("MessageCentor")) {
                    Cfg_CommArg_Msg cfgCommArgMsg = new Cfg_CommArg_Msg();
                    cfgCommArgMsg.setRequest_Set_Flag(0x00); // 查询配置信息
                    int requestFlag = 0;
                    if (strName.equals("APN")) {
                        requestFlag = 0x02;
                    } else if (strName.equals("Heartbeatcycle")) {
                        requestFlag = 0x10;
                    } else if (strName.equals("MessageCentor")) {
                        requestFlag = 0x20;
                    }
                    cfgCommArgMsg.setRequest_Flag(requestFlag);

                    cmd.setCmdFrame(FrameFactory.cfg_commu_SendFrame(strDeviceId.getBytes(), frameNo, cfgCommArgMsg.toByteBuf()));
                    return;
                }
                // 监测点参数查询
                if (strName.equals("MINTimeStamp") || strName.equals("ULValue") || strName.equals("LLValue")
                        || strName.equals("VoltageLevel") || strName.equals("SettleDate")) {
                    Cfg_MPArg_Msg cfgMeasurePointArg = new Cfg_MPArg_Msg();
                    cfgMeasurePointArg.setMeasure_Point_ID(Integer.parseInt(measurePointNo));
                    cfgMeasurePointArg.setRequest_Set_Flag(0x00);
                    int requestFlag = 0;
                    if (strName.equals("MINTimeStamp")) {
                        requestFlag = 0x0001;
                    } else if (strName.equals("ULValue")) {
                        requestFlag = 0x0004;
                    } else if (strName.equals("LLValue")) {
                        requestFlag = 0x0008;
                    } else if (strName.equals("SettleDate")) {
                        requestFlag = 0x0010;
                    } else if (strName.equals("VoltageLevel")) {
                        requestFlag = 0x0020;
                    }
                    cfgMeasurePointArg.setRequest_Flag(requestFlag);

                    cmd.setCmdFrame(FrameFactory.cfg_measure_point_SendFrame(strDeviceId.getBytes(), frameNo, cfgMeasurePointArg.toByteBuf()));
                    return;
                }
                // 装置所属CAC信息查询
                if (strName.equals("CACIP") || strName.equals("CACPhoneNumber")) {
                    Cfg_CACSub_Msg cfgCACSubMsg = new Cfg_CACSub_Msg();
                    cfgCACSubMsg.setRequest_Set_Flag(0x00);
                    int requestFlag = 0;
                    if (strName.equals("CACIP")) {
                        requestFlag = 0x01;
                    } else if (strName.equals("CACPhoneNumber")) {
                        requestFlag = 0x04;
                    }
                    cfgCACSubMsg.setRequest_Flag(requestFlag);

                    cmd.setCmdFrame(FrameFactory.cfg_cac_sub_SendFrame(strDeviceId.getBytes(), frameNo, cfgCACSubMsg.toByteBuf()));
                    return;
                }
                // 装置基本信息查询
                if (strName.equals("VMDModel") || strName.equals("SoftwareVersion") || strName.equals("HardwareVersion")
                        || strName.equals("ProtocolVersion") || strName.equals("BsManufacturer") || strName.equals("BsProductionDate")
                        || strName.equals("VMDPhoneNumber") || strName.equals("VMDCardNumber")) {
                    Cfg_BaseInfo_Msg cfgBaseInfoMsg = new Cfg_BaseInfo_Msg();

                    cmd.setCmdFrame(FrameFactory.cfg_dev_info_SendFrame(strDeviceId.getBytes(), frameNo, cfgBaseInfoMsg.toByteBuf()));
                    return;
                }
                // 工作状态信息查询
                if (strName.equals("TotalWorkingTime") || strName.equals("WorkingTime")) {
                    Cfg_Status_Msg cfgStatusMsg = new Cfg_Status_Msg();

                    cmd.setCmdFrame(FrameFactory.cfg_dev_status_SendFrame(strDeviceId.getBytes(), frameNo, cfgStatusMsg.toByteBuf()));
                    return;
                }
                // 通信流量信息查询
                if (strName.equals("SendFlow") || strName.equals("ReceiveFlow")) {
                    Cfg_Flow_Msg cfg_flow_msg = new Cfg_Flow_Msg();
                    cfg_flow_msg.setDataNum(1);
//                        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM");
//                        int t = (int) (sf.parse("2019-07").getTime() / 1000);
                    List<Element> actionsList = command.getChildren("action");
                    if (actionsList == null) {
                        log.warn("通信流量信息查询 指令action参数 不存在");
                    }
                    String strStartTime = null;
                    for (Element it : actionsList) {
                        if (it.getAttributeValue("name").equals("STARTTIME")) {
                            strStartTime = it.getAttributeValue("value");
                        }
                    }

                    List<String> timeList = new ArrayList();
                    timeList.add(strStartTime);
                    cfg_flow_msg.setDataList(timeList);
                    cmd.setCmdFrame(FrameFactory.cfg_dev_flow_SendFrame(strDeviceId.getBytes(), frameNo, cfg_flow_msg.toByteBuf()));
                    return;
                }
                // 装置ID查询
                if (strName.equals("BsIdentifier") || strName.equals("VMDID")) {
                    Cfg_ID_Msg cfgIdMsg = new Cfg_ID_Msg();
                    cfgIdMsg.setRequest_Set_Flag(0x00);

                    cmd.setCmdFrame(FrameFactory.cfg_dev_id_SendFrame(strDeviceId.getBytes(), frameNo, cfgIdMsg.toByteBuf()));
                    return;
                }
                log.info("error:command(GETCONFIG) is error!!");
                return;
            }
            //  设置配置相关指令
            if (commandType.equals("SETCONFIG")) {  //暂不实现
                Element action = command.getChild("action");
                String strName = action.getAttributeValue("name");
                String strValue = action.getAttributeValue("value");
                log.info(strName);

                // 加入action name
                cmd.setAction(strName);
                //放入到命令信息
                device.getCagCmdList().offer(cmd);

                if (strName.equals("VMDID")) {
                    if (strValue.getBytes().length != 17) {
                        log.info("err:VMDID length");
                    }

                    if (strDeviceId.getBytes().length != 17) {
                        log.info("err:DeviceID length");
                    }
                    Cfg_ID_Msg cfgIdMsg = new Cfg_ID_Msg();
                    cfgIdMsg.setOriginal_ID(strDeviceId.getBytes());
                    cfgIdMsg.setNEW_Device_Code(strValue.getBytes());
                    cfgIdMsg.setRequest_Set_Flag(0x01);

                    cmd.setCmdFrame(FrameFactory.cfg_dev_id_SendFrame(strDeviceId.getBytes(), frameNo, cfgIdMsg.toByteBuf()));
                    return;
                }
                log.info("error:command(SETCONFIG) is not valid!");
                return;
            }
            //  召唤数据相关指令
            if (commandType.equals("GETEVENT")           // CAG获取电压监测装置的事件
                    || commandType.equals("GETDATA")          // CAG获取CAC或所辖监测装置的电压监测数据
                    || commandType.equals("GETDSTATDATA")     // CAG获取CAC或监测装置的日统计数据
                    || commandType.equals("GETMSTATDATA")) {  // CAG获取CAC或监测装置的月统计数据
                List<Element> actionsList = command.getChildren("action");
                if (actionsList == null) {
                    log.warn("action is not set.");
                }
                String strStartTime = null;
                String strEndTime = null;
                for (Element it : actionsList) {
                    if (it.getAttributeValue("name").equals("STARTTIME")) {
                        strStartTime = it.getAttributeValue("value");
                    }
                    if (it.getAttributeValue("name").equals("ENDTIME")) {
                        strEndTime = it.getAttributeValue("value");
                    }
                }
                if (strStartTime == null || strEndTime == null) {
                    log.warn("指令参数异常：strStartTime == null || strEndTime == null");
                }
                // 加入action name
                cmd.setStartTime(strStartTime);
                cmd.setEndTime(strEndTime);
                //放入到命令信息
                device.getCagCmdList().offer(cmd);

                ReqData_Msg requestDatamsg = new ReqData_Msg();
                requestDatamsg.setMeasure_Point_ID(Integer.parseInt(measurePointNo));

                int requestFlag = 0;
                if (commandType.equals("GETEVENT")) {
                    requestFlag = 0xC4;
                } else if (commandType.equals("GETDATA")) {
                    requestFlag = 0x04;
                    log.info("download command：GETDATA");
                } else if (commandType.equals("GETDSTATDATA")) {
                    requestFlag = 0x05;
                    log.info("download command：GETDSTATDATA");

                } else if (commandType.equals("GETMSTATDATA")) {
                    requestFlag = 0x06;
                    log.info("download command：GETMSTATDATA");

                }
                requestDatamsg.setRequest_Type(requestFlag);

                SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date t = ft.parse(strStartTime);
                int startTime = (int) (t.getTime() / 1000);
                log.info("startTime:{}", startTime);
                Date date = ft.parse(strEndTime);
                int endTime = (int) (date.getTime() / 1000);
                log.info("endTime:{}", endTime);

                requestDatamsg.setData_Start_Time(startTime);
                requestDatamsg.setData_End_Time(endTime);

                ByteBuf bf = FrameFactory.request_SendFrame(strDeviceId.getBytes(), frameNo, requestDatamsg.toByteBuf());
                cmd.setCmdFrame(bf);
                return;
            }
            //  升级相关指令
            if (commandType.equals("UPDATENOTICE")) {   // CAG通知CAC或所属监测装置版本更新 暂不实现
                String strSoftVersion = command.getAttributeValue("swversionno");
                String strFileName = command.getAttributeValue("filename");
                return;
            }
            //  重启相关指令
            if (commandType.equals("RESTART")) {      // CAG通知CAC或所属装置进行重启
                return;
            }
            log.info("commandType is error.commandType：{}", commandType);
            return;
        }
    }
}
